package cn.lxycx.dataterrace.util;

import java.util.HashMap;
import java.util.Map;

import lxycx.util.format.DateUtil;
import lxycx.util.run.RandomPro;

/**
 * 验证码模块业务层
 * 场景描述：
 * @author RUNTIME
 * 时间：2018年4月4日
 */
public abstract class YzmVerifyServer {
	
	private Cache cache;//特殊缓存
	private String msgtemp;//通知模板
	private int daycount;//当日次数上限
	private int validatecount;
	private int day_interval_time = 5184000;
	
	private int intervaltime;//间隔时间 秒
	private int validtime;//有效时间
	
	private String intervaltime_key;
	private String daycount_key;
	private String validatecount_key;
	private String yzm_key;

	/**
	 * 初始化数据
	 * @param cache 自定义缓存
	 * @param proname 项目名称
	 * @param scene 场景值
	 * @param msgtemp 短信模板：验证码区域用 **** 标识
	 * @param daycount 当日发送次数上限
	 * @param validatecount 验证次数
	 * @param intervaltime 两次获取间隔时间
	 * @param validtime 有效时间
	 */
	public YzmVerifyServer(Cache cache,String proname,String scene,String msgtemp,int daycount,int validatecount,int intervaltime,int validtime){
		this.cache = cache;
		this.msgtemp = msgtemp;
		this.daycount = daycount;
		this.validatecount = validatecount;
		this.intervaltime = intervaltime;
		this.validtime = validtime;
		
		this.intervaltime_key = proname+":"+scene+":intervaltime:";
		this.daycount_key = proname+":"+scene+":daycount:";
		this.yzm_key = proname+":"+scene+":yzm:";
		this.validatecount_key = proname+":"+scene+":validatecount:";
	}
	
	/**数字型验证码*/
	public Map<String,Object> getNumberYzm(String account,int len){
		String yzm = RandomPro.getVC(len);
		return getYzm(account, yzm);
	}
	
	/**混合型验证码*/
	public Map<String,Object> getMixtureYzm(String account,int len){
		String yzm = RandomPro.getRandomString(len);
		return getYzm(account, yzm);
	}
	
	/**获取验证码*/
	public Map<String,Object> getYzm(String account,String yzm){
		Map<String,Object> ret = new HashMap<String, Object>();
		if(account!=null&&account.trim().length()>0){
			String date = DateUtil.toDay("yyyy-MM-dd");
			
			boolean interval = cache.isEmpty(intervaltime_key+account);//查询间隔时间是到期
			if(interval){
				Long count = cache.incr(daycount_key+date+":"+account);//获取当日发送次数
				if(count<=daycount){
					if(count==1){
						//首次发送设置24小时候自动失效，避免无用数据堆积
						cache.expire(daycount_key+date+":"+account,day_interval_time);
					}
					
					
					String msg = sendMsg(account, msgtemp.replace("****", yzm));
					
					//发送成功再记录发送次数
					if("true".equals(msg)){
						
						//保存验证码到缓存
						cache.set(yzm_key+account, yzm, validtime);
						//设置间隔时间
						cache.expire(intervaltime_key+account, intervaltime);
						//重置验证次数
						cache.set(validatecount_key+account, 0);
						
						ret.put("res", 1);
						ret.put("msg", "发送成功");
					}else{
						ret.put("res", -4);
						ret.put("msg", msg);
					}
					
				}else{
					ret.put("res", -3);
					ret.put("msg", "已达次数上限");
				}
			}else{
				ret.put("res", -2);
				ret.put("msg", "发送频率太快");
			}
		}else{
			ret.put("res", -1);
			ret.put("msg", "账号有误");
		}
		return ret;
	}
	
	
	
	/**校验验证码*/
	public Map<String,Object> valiDateYzm(String account,String yzm){
		Map<String,Object> ret = new HashMap<String, Object>();
		if(account!=null&&account.trim().length()>0){
			long i = cache.incr(validatecount_key+account);
			if(i<=validatecount){
				String yyzm = cache.get(yzm_key+account);
				if(yyzm!=null){
					if(yyzm.equals(yzm)){
						cache.set(yzm_key+account,"");
						ret.put("res", 1);
						ret.put("msg", "校验通过");
					}else{
						ret.put("res", -4);
						ret.put("msg", "校验不通过");
					}
				}else{
					ret.put("res", -3);
					ret.put("msg", "验证码已失效，请先获取验证码");
				}
			}else{
				ret.put("res", -2);
				ret.put("msg", "验证次数达到上限，请重新获取");
			}
		}else{
			ret.put("res", -1);
			ret.put("msg", "账号有误");
		}
		return ret;
	}
	
	
	
	
	
	/**
	 * 发送消息
	 * @param account
	 * @param msg
	 * @return 返回发送结果 true 表示发送成功，其余为失败提示
	 * 创建时间：2018年4月4日
	 */
	protected abstract String sendMsg(String account,String msg);
	
}
